package MelbourneMap;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Abstract class for allowing runnable objects
 * to notify a listener that they have completed
 * their tasks.
 * 
 * @author David Zappia, 7183216
 *
 */
public abstract class NotifyingThread implements Runnable 
{
	  private final Set<ThreadCompleteListener> listeners = new CopyOnWriteArraySet<ThreadCompleteListener>();
	  
	  /**
	   * Add an object that is listening to this thread
	   * 
	   * @param listener	the object that is listening
	   */
	  public final void addListener(final ThreadCompleteListener listener) 
	  {
	    listeners.add(listener);
	  }
	  
	  /**
	   * Remove an object that is currently listening to this thread.
	   * 
	   * @param listener	the object to stop listening
	   */
	  public final void removeListener(final ThreadCompleteListener listener) 
	  {
	    listeners.remove(listener);
	  }
	  
	  /**
	   * Notifies anything listening to this thread
	   * that it has finished.
	   */
	  private final void notifyListeners() 
	  {
	    for (ThreadCompleteListener listener : listeners) 
	      listener.notifyOfThreadComplete(this);
	  }
	  
	  /**
	   * Runs any actions in doRun and then
	   * notifies listeners that it has completed
	   */
	  @Override
	  public final void run() 
	  {
	    try 
	    {
	      doRun();
	    } 
	    finally 
	    {
	      notifyListeners();
	    }
	  }
	  
	  /**
	   * Abstract class to implement any actions
	   * a thread needs to do before completing
	   */
	  public abstract void doRun();
	}
